programming4us
           
 
 
Programming

iPad SDK : New Graphics Functionality - We Are All Tool Users (part 2) - The Pencil Tool

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
12/18/2010 4:13:00 PM

1. The Pencil Tool

The Pencil tool is the simplest one we're going to create. It will place a small dot wherever you tap the screen, or a continuous squiggly line if you continue to drag your finger around.

Make a new NSObject subclass named PencilTool and give it the following content:

//  PencilTool.h
#import <Foundation/Foundation.h>
#import "Tool.h"
@interface PencilTool : NSObject <Tool> {
id <ToolDelegate> delegate;


NSMutableArray *trackingTouches;
NSMutableArray *startPoints;
NSMutableArray *paths;
}
+ (PencilTool *)sharedPencilTool;
@end

// PencilTool.m
#import "PencilTool.h"
#import "PathDrawingInfo.h"
#import "SynthesizeSingleton.h"
@implementation PencilTool
@synthesize delegate;
SYNTHESIZE_SINGLETON_FOR_CLASS(PencilTool);
- init {
if ((self = [super init])) {
trackingTouches = [[NSMutableArray array] retain];
startPoints = [[NSMutableArray array] retain];
paths = [[NSMutableArray array] retain];
}
return self;
}
- (void)activate {
}
- (void)deactivate {
[trackingTouches removeAllObjects];
[startPoints removeAllObjects];
[paths removeAllObjects];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UIView *touchedView = [delegate viewForUseWithTool:self];
for (UITouch *touch in [event allTouches]) {
// remember the touch, and its original start point, for future
[trackingTouches addObject:touch];
CGPoint location = [touch locationInView:touchedView];
[startPoints addObject:[NSValue valueWithCGPoint:location]];
UIBezierPath *path = [UIBezierPath bezierPath];
path.lineCapStyle = kCGLineCapRound;
[path moveToPoint:location];
[path setLineWidth:delegate.strokeWidth];
[path addLineToPoint:location];
[paths addObject:path];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
[self deactivate];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in [event allTouches]) {
// make a line from the start point to the current point
NSUInteger touchIndex = [trackingTouches indexOfObject:touch];
// only if we actually remember the start of this touch...
if (touchIndex != NSNotFound) {
UIBezierPath *path = [paths objectAtIndex:touchIndex];
PathDrawingInfo *info = [PathDrawingInfo pathDrawingInfoWithPath:path
fillColor:[UIColor clearColor] strokeColor:delegate.strokeColor];
[delegate addDrawable:info];



[trackingTouches removeObjectAtIndex:touchIndex];
[startPoints removeObjectAtIndex:touchIndex];
[paths removeObjectAtIndex:touchIndex];
}
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UIView *touchedView = [delegate viewForUseWithTool:self];
for (UITouch *touch in [event allTouches]) {
// make a line from the start point to the current point
NSUInteger touchIndex = [trackingTouches indexOfObject:touch];
// only if we actually remember the start of this touch...
if (touchIndex != NSNotFound) {
CGPoint location = [touch locationInView:touchedView];
UIBezierPath *path = [paths objectAtIndex:touchIndex];
[path addLineToPoint:location];
}
}
}
- (void)drawTemporary {
for (UIBezierPath *path in paths) {
[delegate.strokeColor setStroke];
[path stroke];
}
}
- (void)dealloc {
[trackingTouches release];
[startPoints release];
[paths release];
self.delegate = nil;
[super dealloc];
}
@end


The interesting parts of this code are all contained in the various "touches" methods, which look at all the current touches (yes, this will work with multitouch just fine). In each case, these methods create or modify a Bézier path, or prepare a completed path, using the fill color from the delegate to create a new instance of a DrawablePathDrawingInfo, and pass that to the controller as a complete drawing operation, ready to be added to the DudelView's stack of Drawable objects. object called

PathDrawingInfo is a simple class that conforms to the Drawable protocol we defined earlier. It encapsulates a UIBezierPath and two UIColor values for the stroke and fill. Add a new class called PathDrawingInfo to your project, and give it the following content:

// PathDrawingInfo.h
#import <Foundation/Foundation.h>
#import "Drawable.h"
@interface PathDrawingInfo : NSObject <Drawable> {
UIBezierPath *path;
UIColor *fillColor;
UIColor *strokeColor;
}
@property (retain, nonatomic) UIBezierPath *path;
@property (retain, nonatomic) UIColor *fillColor;

@property (retain, nonatomic) UIColor *strokeColor;
- (id)initWithPath:(UIBezierPath *)p fillColor:(UIColor *)f strokeColor:(UIColor *)s;
+ (id)pathDrawingInfoWithPath:(UIBezierPath *)p fillColor:(UIColor *)f strokeColor:(UIColor *)s;
@end

// PathDrawingInfo.m
#import "PathDrawingInfo.h"
@implementation PathDrawingInfo
@synthesize path, fillColor, strokeColor;
- (id)initWithPath:(UIBezierPath *)p fillColor:(UIColor *)f strokeColor:(UIColor *)s {
if ((self = [self init])) {
path = [p retain];
fillColor = [f retain];
strokeColor = [s retain];
}
return self;
}
+ (id)pathDrawingInfoWithPath:(UIBezierPath *)p fillColor:(UIColor *)f strokeColor:(UIColor *)s {
return [[[self alloc] initWithPath:p fillColor:f strokeColor:s] autorelease];
}
- (void)dealloc {
self.path = nil;
self.fillColor = nil;
self.strokeColor = nil;
[super dealloc];
}
- (void)draw {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
if (self.fillColor) {
[self.fillColor setFill];
[self.path fill];
}
if (self.strokeColor) {
[self.strokeColor setStroke];
[self.path stroke];
}
CGContextRestoreGState(context);
}
@end


The PencilTool class, and all the rest of the Tool classes, also makes use of the SYNTHESIZE_SINGLETON_FOR_CLASS macro. This chunk of code, which comes from Matt Gallagher's Cocoa with Love blog, provides a standardized way to make any class into a singleton. This is perfect for Dudel's tools, since we never need more than one of each kind. This macro overrides all of the methods that deal with memory management, making sure that only one instance of this class is ever created. To use it, add a new header file called SynthesizeSingleton.h to your project, with the following content:

//
// SynthesizeSingleton.h
// CocoaWithLove
//
// Created by Matt Gallagher on 20/10/08.



//

#define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \
\
static classname *shared##classname = nil; \
\
+ (classname *)shared##classname \
{ \
@synchronized(self) \
{ \
if (shared##classname == nil) \
{ \
shared##classname = [[self alloc] init]; \
} \
} \
\
return shared##classname; \
} \
\
+ (id)allocWithZone:(NSZone *)zone \
{ \
@synchronized(self) \
{ \
if (shared##classname == nil) \
{ \
shared##classname = [super allocWithZone:zone]; \
return shared##classname; \
} \
} \
\
return nil; \
} \
\
- (id)copyWithZone:(NSZone *)zone \
{ \
return self; \
} \
\
- (id)retain \
{ \
return self; \
} \
\
- (NSUInteger)retainCount \
{ \
return NSUIntegerMax; \
} \
\
- (void)release \
{ \


} \
\
- (id)autorelease \
{ \
return self; \
}

NOTE

This sort of macro definition is inherently sort of tricky to type in on your own, since the backslash character on each line must come right at the end of the line, without any trailing spaces. Your best bet is to copy this file from the book's source code archive.

You're now very close to being able to try things out! At this point, all that's left to enable the Pencil tool is the addition of a few lines in DudelViewController.m. Start by importing the header:

#import "PencilTool.h"

Then populate the touchPencilItem: method as follows:

- (IBAction)touchPencilItem:(id)sender {
self.currentTool = [PencilTool sharedPencilTool];
[pencilButton setImage:[UIImage imageNamed:@"button_cdots_selected.png"]];
}


Finally, to arrange that this tool is selected by default when the app starts, add a line to the viewDidLoad method:

- (void)viewDidLoad {
[super viewDidLoad];
self.currentTool = [PencilTool sharedPencilTool];
self.fillColor = [UIColor lightGrayColor];
self.strokeColor = [UIColor blackColor];
self.strokeWidth = 2.0;
}

You should now be able to build and run your app. Try tapping and dragging all over the screen with the Pencil tool, making dots and squiggles. Figure 1 shows an example of a drawing made with our new tool.

Figure 1. My god, it's full of dots!
Other -----------------
- Security-As-a-[Cloud] Service : Today’s Offerings
- CSS for Mobile Browsers : CSS Sprites
- CSS for Mobile Browsers : Common Patterns (part 4)
- CSS for Mobile Browsers : Common Patterns (part 3) - Titles and Pseudoclasses
- CSS for Mobile Browsers : Common Patterns (part 2) - Rounded corners
- CSS for Mobile Browsers : Common Patterns (part 1) - Absolute and floating positions
- iPad SDK : New Graphics Functionality - The Basic Drawing Architecture
- jQuery 1.3 : Compact forms (part 6)
- jQuery 1.3 : Compact forms (part 5)
- jQuery 1.3 : Compact forms (part 4)
- jQuery 1.3 : Compact forms (part 3)
- jQuery 1.3 : Compact forms (part 2) - AJAX auto-completion
- jQuery 1.3 : Compact forms (part 1) - Placeholder text for fields
- The Art of SEO : Duplicate Content Issues (part 3)
- The Art of SEO : Duplicate Content Issues (part 2) - How Search Engines Identify Duplicate Content
- The Art of SEO : Duplicate Content Issues (part 1) - Consequences of Duplicate Content
- The Art of SEO : Content Optimization (part 2)
- The Art of SEO : Content Optimization (part 1)
- iPad SDK : New Graphics Functionality - Introducing Dudel (part 2)
- iPad SDK : New Graphics Functionality - Introducing Dudel (part 1)
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us